home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr10 / ehp10.zip / WINDOW.C < prev   
Text File  |  1993-06-19  |  59KB  |  1,520 lines

  1. /****************************************************************/
  2. /*                                                              */
  3. /*      MODUL:  window.c                                        */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*              - adapt_screen (Bildschirm anpassen)            */
  7. /*              - init_win (Fenster-Standards setzen)           */
  8. /*              - print_hilf (Hilfstext in Statuszeile anzeigen)*/
  9. /*              - print_stat (Text in Statuszeile ausgeben)     */
  10. /*              - clear_stat (Statuszeile loeschen)             */
  11. /*              - read_stat (Text in Statuszeile einlesen)      */
  12. /*              - rahmen (Rahmen zeichnen)                      */
  13. /*              - kopf (Kopf in Window-Rahmen schreiben)        */
  14. /*              - open_window (Fenster oeffnen)                 */
  15. /*              - nfr_win (naechstfreie Windownummer ermitteln) */
  16. /*              - koppel_win (Neues Fenster in Liste haengen)   */
  17. /*              - gb_win_frei (Fensterlistenelement freigeben)  */
  18. /*              - pos_cursor (Cursor positionieren)             */
  19. /*              - setz_cursor (Cursor setzen mit kopf neu)      */
  20. /*              - sw_ohne_refresh (aktuelles Window anzeigen)   */
  21. /*              - show_win (Aktuelles Window zeigen und refrsh) */
  22. /*              - text_down (scrolle Window eine Zeile runter)  */
  23. /*              - text_up (scrolle Window eine Zeile hoch)      */
  24. /*              - text_right (Text um eine Position nach rechts)*/
  25. /*              - text_left (Text um eine Position nach links)  */
  26. /*              - fastcharout (Zeichen in Window ausgeben)      */
  27. /*              - lineout (aktuelle Zeile ausgeben)             */
  28. /*              - mal_und_merk (Ecken zeichnen und alte merken) */
  29. /*              - cpwins2stdscr (Fenster in stdscr kopieren)    */
  30. /*              - eckenhw (Ecken zeichnen bzw. loeschen)        */
  31. /*              - win_right (Fenster nach rechts bewegen)       */
  32. /*              - win_left (Fenster nach links bewegen)         */
  33. /*              - win_up (Fenster nach oben bewegen)            */
  34. /*              - win_down (Fenster nach unten bewegen)         */
  35. /*              - size_right (Fenster verbreitern)              */
  36. /*              - size_left (Fenster verschmaelern)             */
  37. /*              - size_up (Unteren Fensterrand nach oben)       */
  38. /*              - size_down (Unteren Fensterrand nach unten)    */
  39. /*              - toggle_size (Gespeicherte Groesse wird akt.)  */
  40. /*              - make_akt_win (Fenster zum aktuellen machen)   */
  41. /*              - sw_name (Fenster gemaess Name suchen)         */
  42. /*              - push_win_back (Fenster in Hintergrund)
  43. /****************************************************************/
  44.  
  45. #include "defs.h"
  46.  
  47. void clear_stat(), setz_cursor(int), show_win(int),
  48.      fastcharout(int,int,char*,int), lineout (int);
  49.  
  50. extern char *fastzeichen();
  51. extern char space;
  52. extern WINDOW *status;
  53. extern char helpflag,backupflag,highblockflag,def_aiflag;
  54. extern int blockattr,in_block(),def_tab;
  55. extern short int *cur_to_poi();
  56.  
  57. /* *** globale Daten und Initialisierung *** */
  58. static int       statx=0;     /* Cursorpositioon X im Statusfenster */
  59. static short int anz_win = 0; /* Anzahl geoeffneter Fenster         */
  60.  
  61. /*****************************************************************************
  62. *
  63. *  Funktion       Bildschirm anpassen (adapt_screen)
  64. *  --------
  65. *
  66. *  Paramater    : begriff   :
  67. *                   Typ         : char *
  68. *                   Wertebereich: Pointer auf ASCII-Zeichenkette
  69. *                   Bedeutung   : String, der vor dem rechten Bildschirm-
  70. *                                 rand Platz haben soll.
  71. *
  72. *  Beschreibung : ws_col und ws_line werden so angepasst, dass die aktuelle
  73. *                 Zeile nach Moeglichkeit in der Mitte des Bildschirms steht
  74. *                 und der Begriff begriff gerade noch vor den rechten Rand
  75. *                 passt.
  76. *
  77. *****************************************************************************/
  78.  
  79. void adapt_screen(begriff)
  80. char *begriff;
  81. {
  82.   /* *** interne Daten und Initialisierung *** */
  83.   int blen=strlen(begriff); /* Laenge des uebergebenen Begriffs */
  84.  
  85.   /* Steht der Cursor schon im Fenster und zwar mindestens blen   */
  86.   /* Zeichen vom rechten Rand entfernt, dann ist alles in Ordnung */
  87.   /* und es wird nur der Cursor an die richtige Position gesetzt  */
  88.   if (akt_winp->textline >= akt_winp->ws_line
  89.   && akt_winp->textline < akt_winp->ws_line+akt_winp->dy
  90.   && akt_winp->screencol >= akt_winp->ws_col
  91.   && akt_winp->screencol < akt_winp->ws_col+akt_winp->dx-blen)
  92.     setz_cursor(W_AKT);
  93.  
  94.   else  /* Cursor nicht im Fenster oder zu weit rechts */
  95.   {
  96.     /* Cursorzeile in die Mitte setzen. Falls Zeilennummer zu klein, */
  97.     /* alles ab erste Zeile anzeigen */
  98.     if ((akt_winp->ws_line = akt_winp->textline - akt_winp->dy/2) < 0)
  99.       akt_winp->ws_line=0;
  100.     /* Fensterinhalt so weit wie moeglich nach rechts. Falls */
  101.     /* Spaltennummer zu klein, alles ab 1. Spalte anzeigen   */
  102.     if ((akt_winp->ws_col=akt_winp->screencol-akt_winp->dx+blen)<0)
  103.       akt_winp->ws_col = 0;
  104.     show_win(W_AKT); /* Fensterinhalt neu anzeigen */
  105.   }
  106. }
  107.  
  108. /*****************************************************************************
  109. *
  110. *  Funktion       Fenster-Standards setzen (init_win)
  111. *  --------
  112. *
  113. *  Beschreibung : Fuer das aktuelle Fenster wird Scrolling verhindert
  114. *                 und der Fensterinhalt geloescht.
  115. *
  116. *****************************************************************************/
  117.  
  118. void init_win()
  119. {
  120.   scrollok(akt_winp->winp,FALSE); /* Nicht scrollen bei Zeilenumbruch */
  121.   werase (akt_winp->winp);        /* Fensterinhalt loeschen           */
  122. }
  123.  
  124. /*****************************************************************************
  125. *
  126. *  Funktion       Hilfstext in Statuszeile anzeigen (print_hilf)
  127. *  --------
  128. *
  129. *  Parameter    : txt       :
  130. *                   Typ          : char*
  131. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  132. *                   Bedeutung    : Auszugebender Text
  133. *
  134. *  Beschreibung : Der Text wird in der Statuszeile ausgegeben. Enthaelt er
  135. *                 ein in runde Klammern eingeschlossenes Zeichen, so wird
  136. *                 dieses Zeichen mit dem Attribut A_STANDOUT versehen.
  137. *
  138. *****************************************************************************/
  139.  
  140. void print_hilf(txt)
  141. register char *txt;
  142. {
  143.   /* *** interne Daten *** */
  144.   register short int c; /* auszugebendes Zeichen */
  145.  
  146.   clear_stat();   /* Statusfenster loeschen */
  147.   wmove(status,0,statx);
  148.   while (*txt)
  149.   {
  150.     if (*txt == '(' && txt[1] && txt[2] == ')')
  151.     { /* Zeichen in Klammern eingeschlossen, dann highlighten */
  152.       c = txt[1] | 256*A_STANDOUT;
  153.       txt+=3;
  154.     }
  155.     else  /* Sonst normal darstellen */
  156.       c = *txt++;
  157.     waddch(status,c);  /* Ins Statusfenster ausgeben */
  158.     statx++;
  159.   }
  160.   wrefresh(status);
  161. }
  162.  
  163. /*****************************************************************************
  164. *
  165. *  Funktion       text in statuszeile ausgeben (print_stat)
  166. *  --------
  167. *
  168. *  Parameter    : txt         :
  169. *                   Typ          : char *
  170. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  171. *                   Bedeutung    : auszugebender Text
  172. *
  173. *  Beschreibung : In dem Fenster status wird in Spalte statx txt
  174. *                 ausgegeben.  Die Variable statx wird um die Laenge des aus-
  175. *                 gegebenen Textes erhoeht.
  176. *
  177. *****************************************************************************/
  178.  
  179. void print_stat(txt)
  180. char *txt;
  181. {
  182.   mvwaddstr(status,0,statx,txt);
  183.   statx+=strlen(txt); /* Spaltenzaehler anpassen */
  184.   wrefresh(status);
  185. }
  186.  
  187. /*****************************************************************************
  188. *
  189. *  Funktion       Statuszeile loeschen (clear_stat)
  190. *  --------
  191. *
  192. *  Beschreibung : Das Fenster status wird geloescht und statx auf 0 gesetzt.
  193. *                 In der Statuszeile werden anschliessend die globalen Flags
  194. *                 angezeigt.
  195. *
  196. *****************************************************************************/
  197.  
  198. void clear_stat()
  199. {
  200.   if (statx) /* Nur wenn schon etwas drinsteht */
  201.   {
  202.     statx = 0;        /* Spaltenzaehler loeschen */
  203.     werase (status);
  204.     wrefresh(status);
  205.   }
  206. }
  207.  
  208.  
  209. /*****************************************************************************
  210. *
  211. *  Funktion       Text in Statuszeile einlesen (read_stat)
  212. *  --------
  213. *
  214. *  Parameter    : input         :
  215. *                   Typ          : char *
  216. *                   Wertebereich : Pointer auf Speicherbereich
  217. *                   Bedeutung    : Bereich, in dem eingegebener Text gespei-
  218. *                                  chert wird
  219. *                 len           :
  220. *                   Typ          : int
  221. *                   Wertebereich : 0 - MAXLENGTH
  222. *                   Bedeutung    : Anzahl einzulesender Zeichen
  223. *
  224. *                 typ           :
  225. *                   Typ          : int
  226. *                   Wertebereich : GS_NUM, GS_ANY
  227. *                   Bedeutung    : GS_NUM: nur Ziffern einlesen
  228. *                                  GS_ANY: alle Zeichen zulassen
  229. *
  230. *  Beschreibung : In der Statuszeile wird ein Text mit max. len Zeichen
  231. *                 Laenge eingelesen.
  232. *
  233. *****************************************************************************/
  234.  
  235. void read_stat(input,len,typ)
  236. char *input;
  237. int len,typ;
  238. {
  239.   newgetstr(status,0,statx,input,len,typ);
  240.   statx += strlen(input); /* Spaltenzaehler anpassen */
  241. }
  242.  
  243.  
  244. /*****************************************************************************
  245. *
  246. *  Funktion       rahmen zeichnen (rahmen)
  247. *  --------
  248. *
  249. *  Parameter    : modus         :
  250. *                   Typ          : int
  251. *                   Wertebereich : W_AKT, W_NOTAKT
  252. *                   Bedeutung    : Angabe, ob Fenster, für das der Rahmen
  253. *                                  gezeichnet werden soll, das aktuelle ist
  254. *                                  oder nicht
  255. *
  256. *  Beschreibung : In das aktuelle Fenster wird rechts und links ein Rand
  257. *                 gezeichnet.
  258. *
  259. *****************************************************************************/
  260.  
  261. void rahmen(modus)
  262. {
  263.   /* *** interne Daten und Initialisierung *** */
  264.   register int i,                 /* Schleifenzaehler    */
  265.            bx=akt_winp->dx+1, /* Breite des Fensters */
  266.            by=akt_winp->dy+1; /* Hoehe des Fensters  */
  267.  
  268.   if(akt_winp->next != akt_winp) /* Nur zeichnen, falls aktuelles Fenster */
  269.   {                              /* nicht das Dummy-Fenster ist. */
  270.     if(modus == W_AKT)
  271.       wstandout(akt_winp->winp); /* Falls aktuelles Fenster, dann highlighten */
  272.     else
  273.       wstandend(akt_winp->winp);
  274.     mvwaddch(akt_winp->winp,1,bx,'');
  275.     mvwaddch(akt_winp->winp,by-1,bx,'');
  276.     for(i=1;i<by;i++)
  277.     {
  278.       mvwaddch(akt_winp->winp,i,0,BORDER_VER);
  279.       mvwaddch(akt_winp->winp,i,bx,BORDER_VER);
  280.     }
  281.     mvwaddch(akt_winp->winp,1,bx,'');
  282.     mvwaddch(akt_winp->winp,by-1,bx,'');
  283.     if(modus == W_AKT)
  284.       wstandend(akt_winp->winp); /* Wurde gehighlightet, dann Highlighten wieder abschalten */
  285.   }
  286. }
  287.  
  288.  
  289. /*****************************************************************************
  290. *
  291. *  Funktion       Kopf in Window-Rahmen schreiben (kopf)
  292. *  --------
  293. *
  294. *  Parameter    : modus         :
  295. *                   Typ          : int
  296. *                   Wertebereich : W_AKT, W_NOTAKT
  297. *                   Bedeutung    : Angabe, ob Fenster, für das der Kopf
  298. *                                  gezeichnet werden soll, das aktuelle ist
  299. *                                  oder nicht
  300. *
  301. *  Beschreibung : In das aktuelle Fenster werden in die oberste (Rahmen) und
  302. *                 in die unterste Zeile Informationen geschrieben. Die Farbe,
  303. *                 in der das geschieht, hängt vom Modus des Fensters ab.
  304. *
  305. *****************************************************************************/
  306.  
  307. void kopf(modus)
  308. int modus;
  309. {
  310.   /* *** interne Daten und Initialisierung *** */
  311.   char         tbuff[BUFFSIZE];   /* Zum Zusammensetzen des Kopf-/Fusszeile */
  312.   register int i,                 /* Schleifenzaehler                       */
  313.            bx=akt_winp->dx+1, /* Fensterbreite                          */
  314.            by=akt_winp->dy+1; /* Fensterhoehe                           */
  315.   static char  kl_template [BUFFSIZE], /* Schablonen zum Erstellen der */
  316.            kf_template [BUFFSIZE], /* Kopf- und Fußzeilen          */
  317.            f_template  [BUFFSIZE],
  318.            init = FALSE;      /* gibt an, ob Schablonen initialisiert   */
  319.  
  320.   if (!init)
  321.   {
  322.     init = TRUE;
  323.     sprintf(kf_template,"%s %%5d%c%s %%5d%c%%s%c%%s%c%%s%c%%s%c%%s",
  324.       PROMPT_LINE, BORDER_HOR, PROMPT_COLUMN, BORDER_HOR,
  325.       BORDER_HOR, BORDER_HOR, BORDER_HOR, BORDER_HOR);
  326.     sprintf(kl_template,"%c%c%c%c %s %c%c%c%c%%s%c%%s%c%%s%c%%s%c%%s",
  327.       BORDER_HOR, BORDER_HOR, BORDER_HOR, BORDER_HOR, PROMPT_WINDOWEMP,
  328.       BORDER_HOR, BORDER_HOR, BORDER_HOR, BORDER_HOR, 
  329.       BORDER_HOR, BORDER_HOR, BORDER_HOR, BORDER_HOR);
  330.     sprintf(f_template,"%c%%d. %s %%s%c%c%%s%c%c%%s",
  331.       BORDER_HOR, PROMPT_WINDOW, BORDER_HOR, BORDER_HOR, BORDER_HOR, 
  332.       BORDER_HOR, BORDER_HOR, BORDER_HOR);
  333.   }
  334.  
  335.   if(akt_winp->next != akt_winp) /* Nur zeichnen, falls aktuelles Fenster */
  336.   {                              /* nicht das Dummy-Fenster ist. */
  337.     if(modus == W_AKT)
  338.       wstandout(akt_winp->winp); /* Bei aktuellen Fenster Rahmen highlighten */
  339.     else
  340.       wstandend(akt_winp->winp);
  341.     mvwaddch (akt_winp->winp,0,bx,''); /* rechte obere Ecke */
  342.     mvwaddch (akt_winp->winp,0,0,'');  /* linke obere Ecke  */
  343.     mvwaddch(akt_winp->winp,by,bx-1,''); /* rechte untere Ecke */
  344.     mvwaddch(akt_winp->winp,by,bx,'\\'); /* rechte untere Ecke */
  345.     mvwaddch(akt_winp->winp,by,0,CORNER_LL);  /* linke untere Ecke  */
  346.     mvwaddch(akt_winp->winp,by,1,'');  /* linke untere Ecke  */
  347.     if (akt_winp->maxline >= 0) /* Fenster nicht leer ? */
  348.       sprintf(tbuff,kf_template,
  349.       akt_winp->textline+1, akt_winp->screencol+1,
  350.       akt_winp->insflag?PROMPT_INSERT:PROMPT_OVERWRITE,
  351.       akt_winp->underflag?PROMPT_UNDERLINE:"",
  352.       akt_winp->autoindflag?"Indent":"",
  353.       akt_winp->shellflag?"SHELL":"",
  354.       akt_winp->tabflag?"Tabs":"Spcs");
  355.     else                        /* Fenster leer */
  356.       sprintf(tbuff,kl_template, akt_winp->insflag?PROMPT_INSERT:
  357.     PROMPT_OVERWRITE, akt_winp->underflag?PROMPT_UNDERLINE:"", 
  358.     akt_winp->autoindflag?"Indent":"",
  359.     akt_winp->shellflag?"SHELL":"", akt_winp->tabflag?"Tabs":"Spcs");
  360.     tbuff[akt_winp->dx] = '\0'; /* Zeile abschneiden, damit sie nicht ueber */
  361.                 /* den Rand hinausgeht. */
  362.     /* Zeile zentriert in erster Fensterzeile anzeigen */
  363.     mvwaddstr(akt_winp->winp,0,1+(akt_winp->dx - strlen(tbuff))/2,tbuff);
  364.     /* Rest des Rahmens in Kopfzeile */
  365.     for (i=1;i<1+(akt_winp->dx - strlen(tbuff))/2;i++)          
  366.       mvwaddch(akt_winp->winp,0,i,BORDER_HOR);
  367.     for (i=1+(akt_winp->dx - strlen(tbuff))/2+strlen(tbuff); i<bx-1;i++)
  368.       mvwaddch(akt_winp->winp,0,i,BORDER_HOR);
  369.  
  370.     /* Fusszeile zusammenbasteln */
  371.     sprintf(tbuff,f_template, akt_winp->wini, akt_winp->filename, 
  372.       akt_winp->read_only?PROMPT_WRTPROTCT:"",
  373.       akt_winp->changeflag?PROMPT_MODIFIED:"");
  374.     tbuff[akt_winp->dx-1]='\0'; /* s.o. */
  375.     mvwaddstr(akt_winp->winp,by,2,tbuff);
  376.     /* Rest des Rahmens in Fusszeile */
  377.     for(i=2+strlen(tbuff);i<bx-1;i++)           
  378.       waddch(akt_winp->winp,BORDER_HOR);
  379.     if(modus == W_AKT)
  380.       wstandend(akt_winp->winp); /* Falls Kopf gehighlightet wurde, Highlighten wieder aus */
  381.   }
  382. }
  383.  
  384. /*****************************************************************************
  385. *
  386. *  Funktion       Fenster oeffnen (open_window)
  387. *  --------
  388. *
  389. *  Beschreibung : Das aktuelle Fenster, fuer das schon Speicher alloziert
  390. *                 sein muss, wird initialisiert : Die (Block-)Koordinaten,
  391. *                 Cursorposition, Fensterstart und Fenstergroesse werden
  392. *                 gesetzt<~s Fenster wird durch Curses angelegt, geloescht
  393. *                 und eingerahmt. Anschliessend wird der Kopf in die oberste
  394. *                 Zeile und die Fusszeile in die unterste Zeile geschrieben.
  395. *
  396. *****************************************************************************/
  397.  
  398. void open_window()
  399. {
  400.   /* Fenster mit Curses anlegen */
  401.   akt_winp->winp = newwin(START_HEIGHT,START_WIDTH,START_Y,START_X);
  402.  
  403.   akt_winp->ws_line = 0; /* Ab erster Zeile anzeigen */
  404.   akt_winp->ws_col = 0;  /* Ab erster Spalte anzeigen */
  405.   akt_winp->ax = akt_winp->x = START_X; /* Fensterposition und */
  406.   akt_winp->ay = akt_winp->y = START_Y; /* alte Fensterposition setzen */
  407.   akt_winp->adx = akt_winp->dx = START_WIDTH-2;  /* Fenstergroesse und alte */
  408.   akt_winp->ady = akt_winp->dy = START_HEIGHT-2; /* Fenstergroesse setzen   */
  409.  
  410.   akt_winp->autoindflag = def_aiflag;
  411.   akt_winp->shellflag = FALSE; /* Default: kein Shellmodus, */
  412.   akt_winp->underflag = FALSE; /* keine Unterstreichung     */
  413.   akt_winp->insflag = TRUE;    /* Insert-Mode               */
  414.   akt_winp->tabflag = TRUE;    /* Blanks zu Tabs kompr.     */
  415.   akt_winp->tablen = def_tab;  /* Tablaenge setzen          */
  416.  
  417.   akt_winp->lastline = akt_winp->lastcol = -1; /* letzte Position setzen */
  418.   akt_winp->block.e_line = akt_winp->block.s_line = -1; /* kein Block */
  419.   init_win();  /* Curses-Defaults fuer Fenster setzen */
  420.   show_win(W_AKT);  /* Fensterinhalt anzeigen */
  421. }
  422.  
  423.  
  424. /*****************************************************************************
  425. *
  426. *  Funktion      naechstfreie Windownummer ermitteln (nfr_win)
  427. *  --------
  428. *
  429. *  Ergebnis     :
  430. *                   Typ          : int
  431. *                   Wertebereich : 0-ANZ_WIN
  432. *                   Bedeutung    : 0 = keine Windownummern mehr frei
  433. *                                  1 - ANZ_WIN = freie Windownummer
  434. *
  435. *  Beschreibung : Die Windowliste wird durchlaufen und nach noch nicht
  436. *                 vergebenen Nummern durchsucht.
  437. *
  438. *****************************************************************************/
  439.  
  440. int nfr_win()
  441. {
  442.   /* *** interne Daten *** */
  443.   register int     i=0; /* Laufende Fensternummer */
  444.   register win_typ *wp; /* Zeiger zum Durchlaufen der Fensterliste */
  445.  
  446.   while (++i<=ANZ_WIN)
  447.   {
  448.     wp = akt_winp->next->next; /* Erstes Element hinter dummy-Element */
  449.     while (wp != akt_winp->next && wp->wini != i)
  450.       wp = wp->next; /* Ganze Liste nach Nummer i absuchen */
  451.     if (wp == akt_winp->next)
  452.       return (i); /* Nummer nicht gefunden, also zurueckgeben */
  453.   }
  454.   return (0); /* 0 : Keine Fensternummer mehr frei */
  455. }
  456.  
  457.  
  458. /*****************************************************************************
  459. *
  460. *  Funktion       Fensterelement allozieren und in Liste koppeln (koppel_win)
  461. *  --------
  462. *
  463. *  Ergebnis     : Typ           : int
  464. *                 Wertebereich  : TRUE, FALSE
  465. *                 Bedeutung     : TRUE : Es gab noch freie Fensternummern
  466. *                                 FALSE : Keine Nummer mehr frei
  467. *
  468. *  Beschreibung : Fuer ein neues Element vom Typ win_typ wird Speicher allo-
  469. *                 ziert.  Das neue Element wird dann in die Windowliste hinter
  470. *                 akt_winp eingehaengt.  Das neue Fenster wird anschliessend
  471. *                 zum aktuellen Fenster.
  472. *
  473. *****************************************************************************/
  474.  
  475. int koppel_win()
  476. {
  477.   /* *** interne Daten *** */
  478.   register win_typ *hilf;   /* Temp. Zeiger auf neues Fenster */
  479.   int              nfr_num; /* Nummer des neuen Fensters      */
  480.  
  481.   /* Testen, ob noch ein Fenster geoeffnet werden kann    */
  482.   /* Klappt nicht, falls schon ANZ_WIN Fenster offen oder */
  483.   /* keine Fensternummer mehr frei                        */
  484.   if ((anz_win < ANZ_WIN) && (nfr_num = nfr_win()))
  485.   {
  486.     anz_win++; /* Ein Fenster mehr geoeffnet */
  487.     hilf = (win_typ*) reserve_mem (sizeof (win_typ));
  488.     hilf->next = akt_winp->next; /* Fenster hinter aktuellem */
  489.     hilf->prev = akt_winp; /* Fenster in Liste einhaengen    */
  490.     akt_winp->next = hilf;
  491.     hilf->next->prev = hilf;
  492.     hilf->wini = nfr_num; /* Naechste freie Windownummer einsetzen */
  493.     hilf->winp = NULL; /* Noch kein Curses-Fenster, wird von print_err erkannt */
  494.     akt_winp = hilf; /* Neues Fenster zum aktuellen machen */
  495.     return (TRUE);
  496.   }
  497.   else
  498.     return(FALSE);
  499. }
  500.  
  501.  
  502. /*****************************************************************************
  503. *
  504. *  Funktion       Fensterlistenelement freigeben  (gb_win_frei)
  505. *  --------
  506. *
  507. *  Beschreibung : Das Element wird aus der Liste herausgenommen und der dazu-
  508. *                 gehoerige Speicher freigegeben.
  509. *
  510. *****************************************************************************/
  511.  
  512. void gb_win_frei ()
  513. {
  514.   /* *** interne Daten *** */
  515.   register win_typ *hilf; /* Zeiger auf momentan aktuelles Fenster */
  516.  
  517.   if ((hilf = akt_winp)->next != hilf) /* Mind. ein Fenster ? */
  518.   {
  519.     anz_win--; /* Ein Fenster weniger geoeffnet */
  520.     line_free(hilf->filename); /* Filenamentext freigeben */
  521.     akt_winp = hilf->prev;     /* Vorgaenger zum aktuellen machen */
  522.     hilf->next->prev = akt_winp; /* Fenster aus Liste auskoppeln  */
  523.     akt_winp->next = hilf->next;
  524.     free (hilf); /* Speicherplatz fuer Fensterstruktur freigeben */
  525.   }
  526. }
  527.  
  528. /*****************************************************************************
  529. *
  530. *  Funktion       cursor positionieren (pos_cursor)
  531. *  --------
  532. *
  533. *  Beschreibung : Cursor wird im aktuellen Fenster an die durch
  534. *                 screencol und textline angegebene Position gesetzt.
  535. *                 Ist der Text leer, wird der Cursor in die erste
  536. *                 Zeile gesetzt.
  537. *
  538. *****************************************************************************/
  539.  
  540. void pos_cursor()
  541. {
  542.   wmove (akt_winp->winp,(akt_winp->maxline == -1)+ /* leer, dann 1 Z. weiter */
  543.      akt_winp->textline-akt_winp->ws_line+1,   /* runter */
  544.      akt_winp->screencol-akt_winp->ws_col+1);
  545.   wrefresh (akt_winp->winp);
  546. }
  547.  
  548. /*****************************************************************************
  549. *
  550. *  Funktion       cursor setzen (setz_cursor)
  551. *  --------
  552. *
  553. *  Parameter    : modus         :
  554. *                   Typ          : int
  555. *                   Wertebereich : W_AKT, W_NOTAKT
  556. *                   Bedeutung    : Angabe, ob Fenster das aktuelle ist und
  557. *                                  somit der Kopf gehighlightet werden soll
  558. *
  559. *  Beschreibung : Cursor wird im aktuellen Fenster an die durch
  560. *                 screencol und textline angegebene Position gesetzt.
  561. *                 Der Kopf wird aktualisiert und das window refresht.
  562. *
  563. *****************************************************************************/
  564.  
  565. void setz_cursor(modus)
  566. int modus;
  567. {
  568.   if(akt_winp->next != akt_winp) /* Nur, wenn ein Fenster offen */
  569.   {
  570.     kopf(modus);  /* Kopf- und Fusszeile anzeigen */
  571.     pos_cursor(); /* Cursor positionieren */
  572.   }
  573. }
  574.  
  575. /*****************************************************************************
  576. *
  577. *  Funktion       Aktuelles Window anzeigen (sw_ohne_refresh)
  578. *  --------
  579. *
  580. *  Parameter    : modus         :
  581. *                   Typ          : int
  582. *                   Wertebereich : W_AKT, W_NOTAKT
  583. *                   Bedeutung    : Angabe, ob Fenster das aktuelle ist und
  584. *                                  somit der Rahmen gehighlightet werden soll
  585. *
  586. *  Beschreibung : Mit der Zeile akt_winp->ws_line beginnend werden
  587. *                 akt_winp->dy Zeilen in dem aktuellen Fenster, bei der
  588. *                 obersten Zeile beginnend, ausgegeben.
  589. *                 Gibt es keine weiteren Textzeilen, so wird der Rest
  590. *                 des Fenster geloescht
  591. *
  592. *****************************************************************************/
  593.  
  594. void sw_ohne_refresh(modus)
  595. int modus;
  596. {
  597.   /* *** interne Daten und Initialisierung *** */
  598.   zeil_typ     *alte_zeile = akt_winp->alinep;   /* Zeiger auf Cursorzeile  */
  599.   register int i,                                /* Zaehler fuer Zeilen     */
  600.            alte_nummer = akt_winp->textline; /* Zeiger auf Zeilennummer */
  601.  
  602.   gotox(akt_winp->ws_line); /* erste anzuzeigende Zeile anspringen */
  603.  
  604.   for(i=0;i<akt_winp->dy;i++)
  605.   {
  606.     lineout(i);    /* Zeile ausgeben */
  607.     if(!down())    /* eine Zeile runter */
  608.     {              /* geht das nicht, dann Rest des Bildschirms loeschen */
  609.       wmove (akt_winp->winp, i+2, 1);
  610.       wclrtobot(akt_winp->winp);
  611.       break;
  612.     }
  613.   }
  614.   rahmen(modus); /* Rahmen anzeigen */
  615.   akt_winp->alinep = alte_zeile;    /* Cursorzeile restaurieren */
  616.   akt_winp->textline = alte_nummer;
  617. }
  618.  
  619.  
  620. /*****************************************************************************
  621. *
  622. *  Funktion       Aktuelles Window anzeigen und refreshen (show_win)
  623. *  --------
  624. *
  625. *  Parameter    : modus         :
  626. *                   Typ          : int
  627. *                   Wertebereich : W_AKT, W_NOTAKT
  628. *                   Bedeutung    : Angabe, ob Fenster das aktuelle ist und
  629. *                                  somit der Rahmen gehighlightet werden soll
  630. *
  631. *  Beschreibung : Mit der Zeile akt_winp->ws_line beginnend werden
  632. *                 akt_winp->dy Zeilen in dem aktuellen Fenster, bei der
  633. *                 obersten Zeile beginnend, ausgegeben.
  634. *                 Gibt es keine weiteren Textzeilen, so wird der Rest
  635. *                 des Fenster geloescht
  636. *
  637. *****************************************************************************/
  638.  
  639. void show_win(modus)
  640. int modus;
  641. {
  642.   sw_ohne_refresh(modus);            /* Fensterinhalt anzeigen */
  643.   setz_cursor(modus);                /* setz_cursor ruft refresh auf */
  644. }
  645.  
  646. /*****************************************************************************
  647. *
  648. *  Funktion       scrolle window um eine zeile nach unten (text_down)
  649. *  --------
  650. *
  651. *  Parameter    : line         :
  652. *                   Typ          : int
  653. *                   Wertebereich : 0 - akt_winp->dy-1
  654. *                   Bedeutung    : Einzufuegende Zeile im Fenster
  655. *
  656. *  Beschreibung : Es wird in der <line>ten Zeile eine Zeile im Fenster ein-
  657. *                 gefuegt. Falls die <line>te Bildschirmzeile exisitert, wird
  658. *                 sie in dieser Zeile angezeigt.
  659. *                 ws_line wird _a_u_f_ _k_e_i_n_e_n_ _F_a_l_l angepasst.
  660. *
  661. *****************************************************************************/
  662.  
  663. void text_down(line)
  664. int line;
  665. {
  666.   /* *** interne Daten *** */
  667.   zeil_typ  *alte_zeile; /* Zwischenspeicher Zeiger auf Cursorzeile */
  668.   int       alte_nummer; /* Zwischenspeicher fuer Zeilennummer      */
  669.   short int rc;          /* Zeichen zum Rahmenrestaurieren          */
  670.  
  671.   if(line == 0)
  672.     rc = REST_ARR_UP;
  673.   else
  674.     if(line == akt_winp->dy-1)
  675.       rc = REST_ARR_DN;
  676.     else
  677.       rc = REST_CHAR;
  678.   wmove(akt_winp->winp,line+1,1); /* Cursor auf uebergebene Zeile stellen */
  679.   winsertln(akt_winp->winp);      /* Eine Zeile im Fenster einfuegen */
  680.  
  681.   if (akt_winp->ws_line+line <= akt_winp->maxline)
  682.   { /* Wenn gewuenschte Zeile existiert: */
  683.     alte_zeile = akt_winp->alinep;    /* aktuelle Zeile merken */
  684.     alte_nummer = akt_winp->textline;
  685.     gotox(akt_winp->ws_line+line);    /* gewuenschte Zeile anspringen */
  686.     lineout(line);                          /* output current line */
  687.     akt_winp->alinep = alte_zeile;    /* Zeilenzeiger restaurieren */
  688.     akt_winp->textline = alte_nummer;
  689.   }
  690.   mvwaddch(akt_winp->winp,line+1,0,REST_CHAR); /* Rahmen reparieren, da durch   */
  691.   mvwaddch(akt_winp->winp,line+1,akt_winp->dx+1,rc); /* insertln korrupt */
  692.   if(line != akt_winp->dy-1) /* Falls nicht in letzter Zeile eingefügt, */
  693.     mvwaddch(akt_winp->winp,akt_winp->dy,akt_winp->dx+1,REST_ARR_DN);
  694.   if(akt_winp->dy > 2) /* Falls Fenster mehr als 1 Zeile hat, gescrollten */
  695.     /* Pfeil durch Rahmenzeichen ersetzen. */
  696.     mvwaddch(akt_winp->winp,2,akt_winp->dx+1,REST_CHAR);
  697. }
  698.  
  699. /*****************************************************************************
  700. *
  701. *  Funktion       scrolle Windowinhalt um eine Zeile nach oben (text_up)
  702. *  --------
  703. *
  704. *  Parameter    : line         :
  705. *                   Typ          : int
  706. *                   Wertebereich : 0 - akt_winp_dy-1
  707. *                   Bedeutung    : Zu loeschende Zeile im Fenster
  708. *
  709. *  Beschreibung : Falls dadurch das Fenster nicht leer wuerde, wird die
  710. *                 <line>te Textzeile des Windows geloescht, so dass
  711. *                 die letzte Zeile frei wird.  In dieser wird die neue
  712. *                 letzte Zeile angezeigt.
  713. *
  714. *****************************************************************************/
  715.  
  716. void text_up(line)
  717. int line;
  718. {
  719.   /* *** interne Daten *** */
  720.   zeil_typ *alte_zeile; /* Zwischenspeicher Zeiger auf Cursorzeile */
  721.   int      alte_nummer; /* Zwischenspeicher fuer Zeilennummer      */
  722.  
  723.   if(line || akt_winp->ws_line <= akt_winp->maxline)
  724.   {
  725.     wmove(akt_winp->winp,line+1,1); /* Cursor in gewuenschte Zeile */
  726.     wdeleteln(akt_winp->winp);      /* Zeile im Fenster loeschen   */
  727.     alte_zeile = akt_winp->alinep;  /* Cursorzeile merken          */
  728.     alte_nummer = akt_winp->textline;
  729.     gotox(akt_winp->ws_line+akt_winp->dy - 1); /* Zur <line>ten Zeile */
  730.     /* Falls die letzte Fensterzeile nicht existiert, Zeilenzeiger */
  731.     /* auf dummy-Element setzen, da dessen Text-Pointer NULL ist.  */
  732.     if(akt_winp->textline != akt_winp->ws_line + akt_winp->dy - 1)
  733.       akt_winp->alinep = akt_winp->dummyp;
  734.     lineout(akt_winp->dy - 1);   /* output current line */
  735.     akt_winp->alinep = alte_zeile;    /* Cursorzeile restaurieren */
  736.     akt_winp->textline = alte_nummer;
  737.     mvwaddch(akt_winp->winp,akt_winp->dy,0,REST_CHAR); /* Rahmen reparieren */
  738.     mvwaddch(akt_winp->winp,akt_winp->dy,akt_winp->dx+1,REST_ARR_DN);
  739.     mvwaddch(akt_winp->winp,1,akt_winp->dx+1,REST_ARR_UP);
  740.     if(akt_winp->dy > 2) /* Falls Fenster mehr als 1 Zeile hat, gescrollten */
  741.       /* Pfeil durch Rahmenzeichen ersetzen. */
  742.       mvwaddch(akt_winp->winp,akt_winp->dy-1,akt_winp->dx+1,REST_CHAR);
  743.   }
  744. }
  745.  
  746. /*****************************************************************************
  747. *
  748. *  Funktion       Text um eine Position nach rechts (text_right)
  749. *  --------
  750. *
  751. *  Beschreibung : alinep wird auf die erste Zeile im Fenster gesetzt.
  752. *                 Dann wird vor jede Zeile ein neuer Character eingefuegt.
  753. *                 Dadurch verschiebt sich der Restliche Text im Fenster
  754. *                 um eine Position nach rechts, wobei das am weitesten
  755. *                 rechts stehende Zeichen "aus dem Fenster faellt".
  756. *
  757. *****************************************************************************/
  758.  
  759. void text_right()
  760. {
  761.   /* *** interne Daten *** */
  762.   zeil_typ     *alte_zeile; /* Zwischenspeicher Zeiger auf Cursorzeile */
  763.   register int i,           /* Zaehler fuer Bildschirmzeile            */
  764.            alte_nummer; /* Zwischenspeicher fuer Zeilennummer      */
  765.  
  766.   if (akt_winp->ws_col > 0) /* Nur, wenn man noch scrollen kann */
  767.   {
  768.     check_buff(); /* evtl. Pufferinhalt in Text kopieren */
  769.     alte_zeile = akt_winp->alinep;    /* Cursorzeile merken */
  770.     alte_nummer = akt_winp->textline;
  771.     akt_winp->ws_col--; /* Nummer der ersten sichtbaren Spalte reduzieren */
  772.     gotox (akt_winp->ws_line); /* Zur ersten sichtbaren Zeile springen */
  773.     for (i=0;i<akt_winp->dy && akt_winp->ws_line+i <= akt_winp->maxline;i++)
  774.     { /* Von allen sichbaren Zeilen das erste sichtbare Zeichen einfuegen */
  775.       fastcharout(i,0,fastzeichen(akt_winp->ws_col),INSERT);
  776.       down(); /* Zur naechsten Zeile gehen */
  777.     }
  778.     akt_winp->alinep = alte_zeile;    /* Cursorzeile restaurieren */
  779.     akt_winp->textline = alte_nummer;
  780.   }
  781. }
  782.  
  783.  
  784. /*****************************************************************************
  785. *
  786. *  Funktion       scrolle Windowinhalt um eine Position nach links (text_left)
  787. *  --------
  788. *
  789. *  Beschreibung : Der Windowinhalt wird um eine Position nach links gescrollt,
  790. *                 so dass rechts neue Zeichen angezeigt werden muessen.
  791. *
  792. *****************************************************************************/
  793.  
  794. void text_left()
  795. {
  796.   /* *** interne Daten *** */
  797.   zeil_typ     *alte_zeile; /* Zwischenspeicher Zeiger auf Cursorzeile */
  798.   register int i,           /* Zaehler fuer Bildschirmzeile            */
  799.            alte_nummer; /* Zwischenspeicher fuer Zeilennummer      */
  800.   short int    rc;          /* Zeichen zum Reparieren des Rahmens      */
  801.  
  802.   if(akt_winp->ws_col < MAXLENGTH)      /* dann nichts mehr auf dem Schirm */
  803.   {
  804.     alte_zeile = akt_winp->alinep;    /* Cursorzeile merken */
  805.     alte_nummer = akt_winp->textline;
  806.     akt_winp->ws_col++; /* Nummer der ersten sichtbaren Spalte erhoehen */
  807.     gotox(akt_winp->ws_line); /* erste sichtbare Zeile anspringen */
  808.     for (i=0;i<akt_winp->dy && akt_winp->ws_line+i-1 < akt_winp->maxline;i++)
  809.     { /* In allen Fensterzeilen erstes Zeichen loeschen */
  810.       mvwdelch(akt_winp->winp,i+1,1);
  811.       fastcharout(i,akt_winp->dx - 1, /* Zeichen in letzer Spalte anzeigen */
  812.           fastzeichen(akt_winp->ws_col + akt_winp->dx-1),PUT);
  813.       if(i == 0)
  814.       rc = REST_ARR_UP;
  815.     else
  816.       if(i == akt_winp->dy-1)
  817.         rc = REST_ARR_DN;
  818.       else
  819.         rc = REST_CHAR;
  820.       mvwaddch(akt_winp->winp,i+1,akt_winp->dx+1,rc);
  821.       down(); /* Rahmen reparieren und zur naechsten Zeile gehen */
  822.     }
  823.     akt_winp->alinep = alte_zeile;    /* Cursorzeile restaurieren */
  824.     akt_winp->textline = alte_nummer;
  825.   }
  826. }
  827.  
  828. /******************************************************************************
  829. *
  830. * Funktion     : Attribute zum Zeichen hinzufügen (add_attrs)
  831. * --------------
  832. *
  833. * Parameter    : ib          :
  834. *                  Typ          : int
  835. *                  Wertebereich : Siehe Ergebnis von in_block
  836. *                  Bedeutung    : Angabe, ob das Zeichen im Block liegt
  837. *
  838. *              : s           :
  839. *                  Typ          : char *
  840. *                  Wertebereich : Zeiger aus ASCII-Zeichenkette
  841. *                  Bedeutung    : Zeiger auf auszugebendes Zeichen
  842. *
  843. * Ergebnis     :
  844. *                  Typ          : short int
  845. *                  Wertebereich : 0-MAXINT
  846. *                  Bedeutung    : Zeichen mit gesetzten Attributen
  847. *
  848. * Beschreibung : Zeigt s auf ein unterstrichenes Zeichen, so wird das
  849. *                Attribut für Unterstreichung zum Ergebnis hinzugeodert.
  850. *                Handelt es sich um einen Controlcode, so wird das Attribut
  851. *                für Invertierung dazugesetzt. Liegt das Zeichen an einer
  852. *                Position, die sich im Block befindet, und sollen Blöcke
  853. *                hervorgehoben werden, dann wird das Blockhighlight-Attribut
  854. *                dazugeodert.
  855. *                Wurde kein Attribut hinzugefügt, so wird das Standardattribut
  856. *                dazugeodert.
  857. *
  858. ******************************************************************************/
  859.  
  860. short int add_attrs(ib,s)
  861. int ib;
  862. char *s;
  863. {
  864.   unsigned short int c;  /* Zur Aufbereitung des Rückgabewertes */
  865.   unsigned int vf, /* Vordergrundfarbe */
  866.            hf; /* Hintergundfarbe */
  867.  
  868.   if(*s == '_' && s[1] == '' && s[2]) /* unterstrichenes Zeichen? */
  869.     c = s[2] | (256*A_UNDERLINE);
  870.   else
  871.     c = *s;
  872.  
  873.   /* Wenn Zeichen im Block, dann highlighten */
  874.   if(highblockflag && ib & B_IN_BLOCK)
  875.     c |= 256*blockattr;   /* Controlcodes werden wieder normal dargestellt */
  876. #ifdef OWN_CURSES
  877.   if(!(c >> 8)) /* Keine Attribute dazugeodert ? */
  878.     c |= 256*STD_ATTR; /* Dann Standardattribut hinzufügen */
  879. #endif
  880.  
  881.   if((c & 255) < 28) /* Controlcodes invertieren */
  882.   {
  883.     vf = c & 3840;  /* Vordergundfarbe ist c & (256*15) */
  884.     hf = c & 61440; /* Hintergrundfarbe ist c & (256*240) */
  885.     /* Vorder- und Hintergrund vertauschen  und 'A' zum Zeichen addieren */
  886.     c = (c & 255) | (vf<<4) | (hf>>4) + 64;
  887.   }
  888.   return (c);
  889. }
  890.  
  891. /*****************************************************************************
  892. *
  893. *  Funktion       Zeichen in window ausgeben (fastcharout)
  894. *  --------
  895. *
  896. *  Parameter:     y         :
  897. *                   Typ          : int
  898. *                   Wertebereich : 0 - Fensterhoehe-1
  899. *                   Bedeutung    : Zeile des Fensters, in dem das Zeichen
  900. *                                  ausgegeben werden soll
  901. *
  902. *                 x         :
  903. *                   Typ          : int
  904. *                   Wertebereich : 0 - Fensterbreite-1
  905. *                   Bedeutung    : Spalte des Fensters, in der das Zeichen
  906. *                                  ausgegeben werden soll
  907. *
  908. *                 s         :
  909. *                   Typ          : char*
  910. *                   Wertebereich : Pointer auf ASCII-Zeichen
  911. *                   Bedeutung    : auszugebendes Zeichen (s. fastzeichen())
  912. *
  913. *                 mode      :
  914. *                   Typ          : int
  915. *                   Wertebereich : INSERT,PUT
  916. *                   Bedeutung    : Gibt an, ob das Zeichen eingefuegt oder ob
  917. *                                  es an die betreffende Stelle kopiert werden
  918. *                                  soll
  919. *
  920. *  Beschreibung : Ist das Zeichen ein unterstrichenes Zeichen, so wird es
  921. *                 unterstrichen ausgegeben; ist der ASCII-Code des Zeichens
  922. *                 kleiner als 28, so wird der Zeichencode um 64 erhoeht und
  923. *                 das Zeichen invers ausgegeben.
  924. *                 Bei den Positionen wird der Rahmen beruecksichtigt, er kann
  925. *                 jedoch im Modus INSERT beschaedigt werden.
  926. *
  927. *****************************************************************************/
  928.  
  929. void fastcharout(y,x,s,mode)
  930. int y,x,mode;
  931. char *s;
  932. {
  933.   /* *** interne Daten und Initialisierung *** */
  934.   register short int c=0; /* Auszugebendes Zeichen     */
  935.   int                ib;  /* Flag, ob Zeichen im Block */
  936.   short int          rc;  /* Zeichen zum Restaurieren des Rahmens */
  937.  
  938.   ib = in_block(y+akt_winp->ws_line,x+akt_winp->ws_col);
  939.   c = add_attrs(ib,s); /* Attribute korrekt setzen */
  940.  
  941.   if(mode & INSERT)
  942.   {
  943.     if(highblockflag && (ib & B_LINE) && !(ib & B_RIGHT)) /* Falls Zeichen in */
  944.     /* einer Blockzeile vor oder im Block muss ganze Zeile neu gezeichnet     */
  945.       lineout(y);         /* werden, da sich die Markierungen verschieben     */
  946.     /* lineout ruft zwar fastcharout auf, jedoch mit dem Modus PUT, also      */
  947.     /* keine Endlos-Rekursion */
  948.     else  /* Wenn Zeichen nicht im Block, dann einfuegen und */
  949.     {     /* Rahmen reparieren */
  950.       if(y == 0)
  951.     rc = REST_ARR_UP;
  952.       else
  953.     if(y == akt_winp->dy-1)
  954.       rc = REST_ARR_DN;
  955.     else
  956.       rc = REST_CHAR;
  957.       mvwinsch(akt_winp->winp,y+1,x+1,c);
  958.       mvwaddch(akt_winp->winp,y+1,akt_winp->dx+1,rc);
  959.     }
  960.   }
  961.   else   /* Bei Modus PUT einfach anzeigen */
  962.     mvwaddch(akt_winp->winp,y+1,x+1,c);
  963. }
  964.  
  965. /*****************************************************************************
  966. *
  967. *  Funktion       aktuelle zeile ausgeben (lineout)
  968. *  --------
  969. *
  970. *  Parameter    : y         :
  971. *                   Typ          : int
  972. *                   Wertebereich : 0 - akt_winp->dy-1
  973. *                   Bedeutung    : Fensterzeile in der Text ausgegeben werden
  974. *                                  soll (Rahmen wird beruecksichtigt)
  975. *
  976. *  Beschreibung : Die aktuelle Zeile wird in dem aktuellen Fenster in Zeile
  977. *                 y ausgegeben. Hat die Zeile weniger Zeichen als das Window
  978. *                 breit ist, so wird der Rest der Zeile geloescht.
  979. *                 Dies geschieht, wenn fastzeichen einen Zeiger auf space
  980. *                 zurueckliefert.
  981. *                 Die Zeichen werden unmittelbar ins Window-Image geschrieben,
  982. *                 wodurch erst ein Refresh die gewollten Ergebnisse
  983. *                 liefert (zu bedenken bei Portierung!)
  984. *                 Die anschließende Position des Cursors ist nicht definiert.
  985. *
  986. *****************************************************************************/
  987.  
  988. #ifdef CUR_DIRECT
  989. void lineout(y)
  990. int y;
  991. {
  992.   /* *** interne Daten *** */
  993.   int           col;    /* aktuelle Fensterspalte */
  994.   register char *s,     /* auszugebendes Zeichen  */
  995.         *zeile; /* Aktuelles Zeichen      */
  996.   unsigned short int *scr,   /* Puffer für anzuzeigende Zeichen */
  997.          *scr_p,     /* Zeiger in scr */
  998.          *scr_image, /* Zeiger ins Screen-image des Fensters */
  999.          rc;         /* Zeichen zum Reparieren des Rahmens */
  1000.  
  1001.   /* Platz für 1 Zeile plus Rahmenzeichen besorgen */
  1002.   scr_p = scr = (short int *) malloc (sizeof (short int)*(akt_winp->dx+1));
  1003.   wmove (akt_winp->winp, y+1, 1);
  1004.   scr_image = cur_to_poi (akt_winp->winp);
  1005.   check_buff(); /* evtl. Pufferinhalt in Text uebertragen */
  1006.   zeile = fastzeichen(akt_winp->ws_col); /* Zeiger auf erstes sichtb. Z. holen */
  1007.  
  1008.   /* Solange nicht alle Bildschirmspalten angezeigt wurden oder */
  1009.   /* die anzuzeigende Zeile zu Ende ist. */
  1010.   for(s = zeile, col=0;(col < akt_winp->dx) && (s!= &space);col++)
  1011.     if (!*zeile)  /* Zeilenende ? */
  1012.     {
  1013.       s = &space; /* Dann s auf globales Space setzen */
  1014.       col--; /* Obwohl kein Zeichen ausgegeben wurde, wird col erhoeht. */
  1015.     }        /* Also muss col hier dekrementiert werden.                */
  1016.     else     /* Kein Zeilenende */
  1017.     {
  1018.       /* Testen, ob zeile nicht hinter oder vor Zeile zeigt und ob */
  1019.       /* aktuelles Zeichen unterstrichen ist. */
  1020.       if(((s = zeile) != &space)
  1021.       && *zeile++ == '_' && *zeile == '' && zeile[1])
  1022.     zeile+=2; /* Unterstrichen, dann zeile um 2 weitere Pos. erhoehen */
  1023.       /* Jetzt mit der Funktion add_attrs die erforderlichen Attribute */
  1024.       /* hinzufügen und das Zeichen anzeigen                           */
  1025.       *scr_image++ =
  1026.       *scr_p++ = add_attrs(in_block(y+akt_winp->ws_line,col+akt_winp->ws_col),s);
  1027.     }
  1028.  
  1029.   if(col < akt_winp->dx)
  1030.   /* Wenn noch nicht am Fensterrand, dann Rest der Zeile loeschen */
  1031.     for (; col<akt_winp->dx; col++)
  1032.       *scr_image++ = *scr_p++ = 256*STD_ATTR;
  1033.  
  1034.   /* Jetzt Rahmen restaurieren */
  1035.   if(y == 0)
  1036.       *scr_image++ = *scr_p++ = REST_ARR_UP;
  1037.     else
  1038.       if(y == akt_winp->dy-1)
  1039.     *scr_image++ = *scr_p++ = REST_ARR_DN;
  1040.       else
  1041.     *scr_image++ = *scr_p++ = REST_CHAR;
  1042.  
  1043.   /* Jetzt den zusammengesetzten String ausgeben */
  1044.   VioWrtCellStr (scr, sizeof(short int) * (akt_winp->dx+1),
  1045.          akt_winp->winp->_start_y+y+1,
  1046.          akt_winp->winp->_start_x+1, 0);
  1047.   free (scr);
  1048. }
  1049.  
  1050. #else
  1051.  
  1052. void lineout(y)
  1053. int y;
  1054. {
  1055.   /* *** interne Daten *** */
  1056.   int           col;    /* aktuelle Fensterspalte */
  1057.   register char *s,     /* auszugebendes Zeichen  */
  1058.         *zeile; /* Aktuelles Zeichen      */
  1059.   unsigned short int *scr,   /* Zeiger in Fenster      */
  1060.          rc;         /* Zeichen zum Reparieren des Rahmens */
  1061.  
  1062.   check_buff(); /* evtl. Pufferinhalt in Text uebertragen */
  1063.   zeile = fastzeichen(akt_winp->ws_col); /* Zeiger auf erstes sichtb. Z. holen */
  1064.   wmove(akt_winp->winp,y+1,1); /* Cursor zum Zeilenanfang bewegen */
  1065.  
  1066.   /* Solange nicht alle Bildschirmspalten angezeigt wurden oder */
  1067.   /* die anzuzeigende Zeile zu Ende ist. */
  1068.   for(s = zeile, col=0;(col < akt_winp->dx) && (s!= &space);col++)
  1069.     if (!*zeile)  /* Zeilenende ? */
  1070.     {
  1071.       s = &space; /* Dann s auf globales Space setzen */
  1072.       col--; /* Obwohl kein Zeichen ausgegeben wurde, wird col erhoeht. */
  1073.     }        /* Also muss col hier dekrementiert werden.                */
  1074.     else     /* Kein Zeilenende */
  1075.     {
  1076.       /* Testen, ob zeile nicht hinter oder vor Zeile zeigt und ob */
  1077.       /* aktuelles Zeichen unterstrichen ist. */
  1078.       if(((s = zeile) != &space)
  1079.       && *zeile++ == '_' && *zeile == '' && zeile[1])
  1080.     zeile+=2; /* Unterstrichen, dann zeile um 2 weitere Pos. erhoehen */
  1081.       /* Jetzt mit der Funktion add_attrs die erforderlichen Attribute */
  1082.       /* hinzufügen und das Zeichen anzeigen                           */
  1083.       waddch (akt_winp->winp, 
  1084.           add_attrs(in_block(y+akt_winp->ws_line,col+akt_winp->ws_col),s));
  1085.     }
  1086.  
  1087.   if(col < akt_winp->dx)
  1088.   { /* Wenn noch nicht am Fensterrand, dann Rest der Zeile loeschen */
  1089.     wmove(akt_winp->winp,y+1,col+1);
  1090.     wclrtoeol(akt_winp->winp);
  1091.   }
  1092.   if(y == 0)
  1093.       rc = REST_ARR_UP;
  1094.     else
  1095.       if(y == akt_winp->dy-1)
  1096.     rc = REST_ARR_DN;
  1097.       else
  1098.     rc = REST_CHAR;
  1099.   mvwaddch(akt_winp->winp,y+1,akt_winp->dx+1,rc); /* Rahmen reparieren */
  1100. }
  1101. #endif
  1102.  
  1103. /*****************************************************************************
  1104. *
  1105. *  Funktion       Ecken zeichnen und alte Zeichen merken (mal_und_merk)
  1106. *  --------
  1107. *
  1108. *  Parameter    : y         :
  1109. *                   Typ          : int
  1110. *                   Wertebereich : 0 - LINES-2
  1111. *                   Bedeutung    : Zeile,in der Ecke erscheinen soll
  1112. *
  1113. *                 x         :
  1114. *                   Typ          : int
  1115. *                   Wertebereich : 0 - COLS-1
  1116. *                   Bedeutung    : Spalte, in der Ecke erscheinen soll
  1117. *
  1118. *                 num       :
  1119. *                   Typ          : int
  1120. *                   Wertebereich : 0-3
  1121. *                   Bedeutung    : Nummer der Ecke
  1122. *
  1123. *  Beschreibung : Die Funktion merkt sich die Zeichen, die da stehen, wo die
  1124. *                 Ecken erscheinen sollen. Dann werden diese Zeichen durch
  1125. *                 die alten gemerkten Zeichen (anfangs '+') ersetzt.
  1126. *
  1127. *****************************************************************************/
  1128.  
  1129. void mal_und_merk(y,x,num)
  1130. int y,x,num;
  1131. {
  1132.   /* *** interne Daten und Initialisierung *** */
  1133.   static short int alt_zeich [4] = {'+','+','+','+'}; /* alte Zeichen */
  1134.   short int        hilf;   /* Zwischenspeicher fuer gelesenes Zeichen */
  1135.  
  1136.   hilf = mvinch (y,x);  /* Zeichen aus dem Bildschirm lesen */
  1137.   mvaddch (y,x,alt_zeich [num]); /* Altes Zeichen hinsetzen */
  1138.   alt_zeich [num] = hilf; /* gelesenes Zeichen als altes Zeichen merken */
  1139. }
  1140.  
  1141. /*****************************************************************************
  1142. *
  1143. *  Funktion       Fensterinhalte nach stdscr uebertragen (cpwins2stdscr)
  1144. *  --------
  1145. *
  1146. *  Beschreibung : Es werden alle Fenster ausser dem aktuellen ins stdscr-
  1147. *                 Fenster uebertragen. Dazu wird die Funktion overlay benutzt.
  1148. *
  1149. *****************************************************************************/
  1150.  
  1151. void cpwins2stdscr()
  1152. {
  1153.   /* *** interne Daten und Initialisierung *** */
  1154.   win_typ *w = akt_winp->next->next; /* Pointer fuer Windowliste */
  1155.  
  1156.   while(w != akt_winp)
  1157.   {
  1158.     overwrite(w->winp,stdscr);
  1159.     w = w->next;
  1160.   }
  1161.   refresh();
  1162. }
  1163.  
  1164. /*****************************************************************************
  1165. *
  1166. *  Funktion       Ecken zeichnen bzw. loeschen (eckenhw)
  1167. *  --------
  1168. *
  1169. *  Beschreibung : Es werden die Eckpunkte des aktuellen Fensters durch die
  1170. *                 Zeichen, die vorher dort standen (anfangs '+') ersetzt.
  1171. *
  1172. *****************************************************************************/
  1173.  
  1174. void eckenhw()
  1175. {
  1176.   mal_und_merk (akt_winp->y,akt_winp->x,0);
  1177.   mal_und_merk (akt_winp->y,akt_winp->x+akt_winp->dx+1,1);
  1178.   mal_und_merk (akt_winp->y+akt_winp->dy+1,akt_winp->x,2);
  1179.   mal_und_merk (akt_winp->y+akt_winp->dy+1,akt_winp->x+akt_winp->dx+1,3);
  1180.   refresh();
  1181. }
  1182.  
  1183. /*****************************************************************************
  1184. *
  1185. *  Funktion       Fenster nach rechts bewegen (win_right)
  1186. *  --------
  1187. *
  1188. *  Parameter    : steps     :
  1189. *                   Typ          : int
  1190. *                   Wertebereich : 0 - MAXINT
  1191. *                   Bedeutung    : Schritte, um die verschoben werden soll
  1192. *
  1193. *  Beschreibung : Funktion prueft, ob Fenster nach rechts geschoben werden
  1194. *                 kann. Wenn ja, wird Startposition x inkrementiert.
  1195. *
  1196. *****************************************************************************/
  1197.  
  1198. void win_right(steps)
  1199. int steps;
  1200. {
  1201.   if ((akt_winp->x += steps)+akt_winp->dx+1 >= COLS)
  1202.     akt_winp->x = COLS-akt_winp->dx-2;
  1203. }
  1204.  
  1205. /*****************************************************************************
  1206. *
  1207. *  Funktion       Fenster nach links verschieben (win_left)
  1208. *  --------
  1209. *
  1210. *  Parameter    : steps     :
  1211. *                   Typ          : int
  1212. *                   Wertebereich : 0 - MAXINT
  1213. *                   Bedeutung    : Schritte, um die verschoben werden soll
  1214. *
  1215. *  Beschreibung : Fall Fenster noch nicht am linken Bildschirmrand, dann
  1216. *                 Fensterstart x dekrementieren.
  1217. *
  1218. *****************************************************************************/
  1219.  
  1220. void win_left(steps)
  1221. int steps;
  1222. {
  1223.   if ((akt_winp->x -= steps) < START_X)
  1224.     akt_winp->x = START_X;
  1225. }
  1226.  
  1227. /*****************************************************************************
  1228. *
  1229. *  Funktion       Window nach oben verschieben (win_up)
  1230. *  --------
  1231. *
  1232. *  Parameter    : steps     :
  1233. *                   Typ          : int
  1234. *                   Wertebereich : 0 - MAXINT
  1235. *                   Bedeutung    : Schritte, um die verschoben werden soll
  1236. *
  1237. *  Beschreibung : Falls Fenster nicht am oberen Bildschirmrand, Startadresse
  1238. *                 y dekrementieren
  1239. *
  1240. *****************************************************************************/
  1241.  
  1242. void win_up(steps)
  1243. int steps;
  1244. {
  1245.   if ((akt_winp->y -= steps) < START_Y)
  1246.     akt_winp->y = START_Y;
  1247. }
  1248.  
  1249. /*****************************************************************************
  1250. *
  1251. *  Funktion       Fenster nach unten verschieben (win_down)
  1252. *  --------
  1253. *
  1254. *  Parameter    : steps     :
  1255. *                   Typ          : int
  1256. *                   Wertebereich : 0 - MAXINT
  1257. *                   Bedeutung    : Schritte, um die verändert werden soll
  1258. *
  1259. *  Beschreibung : Falls Fenster noch nicht am unteren Bildschirmrand, wird
  1260. *                 Fensterstartadresse y inkrementiert.
  1261. *
  1262. *****************************************************************************/
  1263.  
  1264. void win_down(steps)
  1265. int steps;
  1266. {
  1267.   if ((akt_winp->y += steps)+akt_winp->dy+2 >= LINES)
  1268.     akt_winp->y = LINES-akt_winp->dy-3;
  1269. }
  1270.  
  1271. /*****************************************************************************
  1272. *
  1273. *  Funktion       Fenster verbreitern (size_right)
  1274. *  --------
  1275. *
  1276. *  Parameter    : steps     :
  1277. *                   Typ          : int
  1278. *                   Wertebereich : 0 - MAXINT
  1279. *                   Bedeutung    : Schritte, um die verändert werden soll
  1280. *
  1281. *  Beschreibung : Falls die rechte Seite des Fensters nicht am rechten Bild-
  1282. *                 schirmrand ist, wird das Fenster um eine Position
  1283. *                 verbreitert
  1284. *
  1285. *****************************************************************************/
  1286.  
  1287. void size_right(steps)
  1288. int steps;
  1289. {
  1290.   if (akt_winp->x+(akt_winp->dx += steps)+1 >= COLS)
  1291.     akt_winp->dx = COLS-akt_winp->x-2;
  1292. }
  1293.  
  1294. /*****************************************************************************
  1295. *
  1296. *  Funktion       Fenster verschmaelern (size_left)
  1297. *  --------
  1298. *
  1299. *  Parameter    : steps     :
  1300. *                   Typ          : int
  1301. *                   Wertebereich : 0 - MAXINT
  1302. *                   Bedeutung    : Schritte, um die verändert werden soll
  1303. *
  1304. *  Beschreibung : Falls das Fenster eine Breite > 1 hat, wird es um eine
  1305. *                 Position verschmaelert.
  1306. *
  1307. *****************************************************************************/
  1308.  
  1309. void size_left(steps)
  1310. int steps;
  1311. {
  1312.   if ((akt_winp->dx -= steps) < 1)
  1313.     akt_winp->dx = 1;
  1314. }
  1315.  
  1316. /*****************************************************************************
  1317. *
  1318. *  Funktion       Unteren Fensterrand nach oben ziehen (size_up)
  1319. *  --------
  1320. *
  1321. *  Parameter    : steps     :
  1322. *                   Typ          : int
  1323. *                   Wertebereich : 0 - MAXINT
  1324. *                   Bedeutung    : Schritte, um die verändert werden soll
  1325. *
  1326. *  Beschreibung : Falls das Fenster mehr als eine Zeile hat, wird
  1327. *                 die Hoehe des Fenstern dekrementiert.
  1328. *
  1329. *****************************************************************************/
  1330.  
  1331. void size_up(steps)
  1332. int steps;
  1333. {
  1334.   if ((akt_winp->dy -= steps) < 1)
  1335.     akt_winp->dy = 1;
  1336. }
  1337.  
  1338. /*****************************************************************************
  1339. *
  1340. *  Funktion       Unteren Fensterrand nach unten schieben (size_down)
  1341. *  --------
  1342. *
  1343. *  Parameter    : steps     :
  1344. *                   Typ          : int
  1345. *                   Wertebereich : 0 - MAXINT
  1346. *                   Bedeutung    : Schritte, um die verändert werden soll
  1347. *
  1348. *  Beschreibung : Falls der untere Fensterrand nicht am unteren Bild-
  1349. *                 schirmrand ist, wird die Fensterhoehe inkrementiert.
  1350. *
  1351. *****************************************************************************/
  1352.  
  1353. void size_down(steps)
  1354. int steps;
  1355. {
  1356.   if (akt_winp->y+(akt_winp->dy += steps)+1 >= LINES-1)
  1357.     akt_winp->dy = LINES-akt_winp->y-3;
  1358. }
  1359.  
  1360. /*****************************************************************************
  1361. *
  1362. *  Funktion       Gespeicherte Groesse wird aktuelle Groesse (toggle_size)
  1363. *  --------
  1364. *
  1365. *  Beschreibung : Die gespeicherte Groesse wird mit der aktuellen vertauscht.
  1366. *                 Die aktuelle Zeile wird moeglichst in die Mitte des
  1367. *                 Fensters gesetzt, seitlich wird der Fensterinhalt moeglichst
  1368. *                 weit nach rechts geschoben.
  1369. *
  1370. *****************************************************************************/
  1371.  
  1372. void toggle_size()
  1373. {
  1374.   swap_int(&akt_winp->dx,&akt_winp->adx);
  1375.   swap_int(&akt_winp->dy,&akt_winp->ady);
  1376.   swap_int(&akt_winp->x,&akt_winp->ax);
  1377.   swap_int(&akt_winp->y,&akt_winp->ay);
  1378.  
  1379.   if ((akt_winp->ws_line = akt_winp->textline - akt_winp->dy/2) < 0)
  1380.     akt_winp->ws_line=0;
  1381.   if ((akt_winp->ws_col=akt_winp->screencol-akt_winp->dx+1)<0)
  1382.     akt_winp->ws_col = 0;
  1383.  
  1384.   werase(akt_winp->winp);   /* Fensterinhalt loeschen */
  1385.   wrefresh(akt_winp->winp);
  1386.   delwin(akt_winp->winp);   /* Fenster entfernen und neu erstellen */
  1387.   akt_winp->winp = newwin(akt_winp->dy+2,akt_winp->dx+2,akt_winp->y,akt_winp->x);
  1388.   init_win();  /* Fensterdefault mit Curses setzen */
  1389. }
  1390.  
  1391. /*****************************************************************************
  1392. *
  1393. *  Funktion       Fenster zum aktuellen Fenster machen (make_akt_win)
  1394. *  --------
  1395. *
  1396. *  Parameter    : n         :
  1397. *                   Typ          : int
  1398. *                   Wertebereich : 0-ANZ_WIN
  1399. *                   Bedeutung    : Nummer des Fensters, das zum aktuellen
  1400. *                                  gemacht werden soll.
  1401. *
  1402. *  Ergebnis     :
  1403. *                   Typ          : int
  1404. *                   Wertebereich : TRUE, FALSE
  1405. *                   Bedeutung    : TRUE  : Fenster noch da
  1406. *                                  FALSE : Fenster nicht mehr da
  1407. *
  1408. *  Beschreibung : Die Liste der Fenster wird auf ein Fenster mit der Nummer
  1409. *                 n durchsucht. Wird es gefunden, so wird es zum aktuellen,
  1410. *                 und es wird TRUE zurueckgegeben. Sonst bleibt das aktuelle
  1411. *                 Fenster unveraendert und es wird FALSE zurueckgegeben.
  1412. *
  1413. *****************************************************************************/
  1414.  
  1415. int make_akt_win(n)
  1416. register int n;
  1417. {
  1418.   /* *** interne Daten *** */
  1419.   register win_typ *w,     /* Zum Durchlaufen der Fensterliste */
  1420.            *dummy; /* Zum Umhaengen der Fenster        */
  1421.  
  1422.   if(akt_winp->wini == n)       /* wieso in der Ferne schweifen... */
  1423.     return(TRUE);               /* aktuelles ist gewuenschtes Fenster */
  1424.  
  1425.   for(w=akt_winp->next->next;w != akt_winp && w->wini != n;w = w->next);
  1426.  
  1427.   if(w->wini == n)              /* gefunden? */
  1428.   {
  1429.     dummy = akt_winp->next;     /* Dann gefundenes Fenster zum aktuellen */
  1430.     akt_winp->next = w;         /* machen, indem es vor dummy einge-     */
  1431.     w->prev->next = w->next;    /* koppelt wird.                         */
  1432.     w->next->prev = w->prev;
  1433.     w->prev = akt_winp;
  1434.     w->next = dummy;
  1435.     dummy->prev = w;
  1436.     akt_winp = w;
  1437.     return(TRUE);
  1438.   }
  1439.   return(FALSE);
  1440. }
  1441.  
  1442. /*****************************************************************************
  1443. *
  1444. *  Funktion       Fenster gemaess Filename suchen (sw_name)
  1445. *  --------
  1446. *
  1447. *  Parameter    : fn        :
  1448. *                   Typ          : char*
  1449. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  1450. *                   Bedeutung    : Name des Fensters, das zum aktuellen
  1451. *                                  gemacht werden soll.
  1452. *
  1453. *  Ergebnis     :
  1454. *                   Typ          : int
  1455. *                   Wertebereich : TRUE, FALSE
  1456. *                   Bedeutung    : TRUE  : Fenster gefunden
  1457. *                                  FALSE : Fenster nicht gefunden
  1458. *
  1459. *  Beschreibung : Die Liste der Fenster wird auf ein Fenster mit dem Namen
  1460. *                 fn durchsucht. Wird es gefunden, so wird es zum aktuellen,
  1461. *                 und es wird TRUE zurueckgegeben. Sonst bleibt das aktuelle
  1462. *                 Fenster unveraendert und es wird FALSE zurueckgegeben.
  1463. *
  1464. *****************************************************************************/
  1465.  
  1466. int sw_name(fn)
  1467. register char *fn;
  1468. {
  1469.   register win_typ *w,     /* Zum Durchlaufen der Fensterliste */
  1470.            *dummy; /* Zum Umhaengen der Fenster        */
  1471.  
  1472.   for(w=akt_winp->next->next;w!=akt_winp && strcmp(w->filename,fn);w=w->next);
  1473.  
  1474.   if(w != akt_winp)                     /* gefunden? */
  1475.   {
  1476.     dummy = akt_winp->next;   /* Dann gefundenes Fenster zum aktuellen */
  1477.     akt_winp->next = w;       /* machen, indem man es vor dummy in     */
  1478.     w->prev->next = w->next;  /* die Fensterliste einhaengt.           */
  1479.     w->next->prev = w->prev;
  1480.     w->prev = akt_winp;
  1481.     w->next = dummy;
  1482.     dummy->prev = w;
  1483.     akt_winp = w;
  1484.     return(TRUE);
  1485.   }
  1486.   /* Wenn aktuelles Fenster richtig war, dann TRUE, sonst FALSE */
  1487.   if (akt_winp->filename)
  1488.     return(!strcmp(akt_winp->filename,fn));
  1489.   else
  1490.     return FALSE; /* Kein Fenster offen, dann nicht gefunden */
  1491. }
  1492.  
  1493. /******************************************************************************
  1494. *
  1495. * Funktion     : Fenster in Hintergrund schieben (push_win_back)
  1496. * --------------
  1497. *
  1498. * Beschreibung : Das aktuelle Fenster wird zum Fenster, das als erstes
  1499. *                gezeichnet wird. Dadurch erscheint es für den Benutzer
  1500. *                im Hintergrund.
  1501. *
  1502. ******************************************************************************/
  1503.  
  1504. void push_win_back()
  1505. {
  1506.   win_typ *dummy=akt_winp->next; /* Zum Umhängen der Fenster */
  1507.  
  1508.   if(akt_winp->next->next != akt_winp)
  1509.   {
  1510.     dummy->next->prev = akt_winp;
  1511.     akt_winp->next = dummy->next;
  1512.     dummy->prev = akt_winp->prev;
  1513.     dummy->prev->next = dummy;
  1514.     dummy->next = akt_winp;
  1515.     akt_winp->prev = dummy;
  1516.     akt_winp = dummy->prev;
  1517.   }
  1518. }
  1519.  
  1520.